package top.cardone.context.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Setter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;
import top.cardone.context.Contexts;

import java.util.Collection;
import java.util.Map;

/**
 * 字符串工具类
 *
 * @author yao hai tao
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {
    @lombok.Setter
    private static java.util.Map<String, AntPathMatcher> pathMatcherMap = Maps.newConcurrentMap();
    @Setter
    private static Map<String, String> escapeSqlMap;

    static {
        escapeSqlMap = Maps.newHashMap();

        escapeSqlMap.put("'", "''");
        escapeSqlMap.put("\\\\", "\\\\\\\\");
        escapeSqlMap.put("%", "\\\\%");
        escapeSqlMap.put("_", "\\\\_");
    }

    private StringUtils() {
    }

    /**
     * 返回不为空的字符串
     *
     * @param strs 字符串集合
     * @return 不为空的字符串
     */
    public static String defaultIfBlank(final String... strs) {
        if (org.apache.commons.lang3.ArrayUtils.isEmpty(strs)) {
            return null;
        }

        for (final String str : strs) {
            if (org.apache.commons.lang3.StringUtils.isNotBlank(str)) {
                return str;
            }
        }

        return null;
    }

    /**
     * 获取路径
     *
     * @param paths 路径集合
     * @param url   路径
     * @return 路径
     */
    public static String getPathForMatch(final java.util.Collection<String> paths, final String url) {
        return getPathForMatch(null, paths, url);
    }

    /**
     * 获取路径
     *
     * @param pathSeparator 路径间隔
     * @param paths         路径集合
     * @param url           路径
     * @return 路径
     */
    public static String getPathForMatch(String pathSeparator, final Collection<String> paths, final String url) {
        if (CollectionUtils.isEmpty(paths)) {
            return null;
        }

        if (org.apache.commons.lang3.StringUtils.isBlank(url)) {
            return null;
        }

        PathMatcher pathMatcher = StringUtils.getPathMatcher(pathSeparator);

        for (final String path : paths) {
            if (pathMatcher.match(path, url)) {
                return path;
            }
        }

        return null;
    }

    /**
     * 获取路径比较
     *
     * @return 路径比较
     */
    public static PathMatcher getPathMatcher() {
        return getPathMatcher(null);
    }

    /**
     * 获取路径比较
     *
     * @param pathSeparator 路径间隔
     * @return 路径比较
     */
    public static PathMatcher getPathMatcher(String pathSeparator) {
        String newPathSeparator = org.apache.commons.lang3.StringUtils.defaultIfBlank(pathSeparator, AntPathMatcher.DEFAULT_PATH_SEPARATOR);

        AntPathMatcher antPathMatcher = StringUtils.pathMatcherMap.get(newPathSeparator);

        if (antPathMatcher == null) {
            antPathMatcher = new AntPathMatcher(newPathSeparator);

            pathMatcherMap.put(newPathSeparator, antPathMatcher);
        }

        antPathMatcher.setCachePatterns(true);

        return antPathMatcher;
    }

    /**
     * 比较
     *
     * @param paths 路径集合
     * @param url   路径
     * @return 比较结果
     */
    public static boolean matchs(final Collection<String> paths, final String url) {
        if (CollectionUtils.isEmpty(paths)) {
            return false;
        }

        String path = StringUtils.getPathForMatch(paths, url);

        return org.apache.commons.lang3.StringUtils.isNotBlank(path);
    }

    /**
     * 比较
     *
     * @param pathsStr 路径集合
     * @param url      路径
     * @return 比较结果
     */
    public static boolean matchs(final String pathsStr, final String url) {
        final Collection<String> paths = Lists.newArrayList(org.apache.commons.lang3.StringUtils.split(pathsStr, Contexts.comma.stringValue()));

        return StringUtils.matchs(paths, url);
    }

    /**
     * 批量替换字符串
     *
     * @param text           文本
     * @param replacementMap 替换字符串映射
     * @return 替换后字符串
     */
    public static String replaces(String text, Map<String, String> replacementMap) {
        if (isBlank(text)) {
            return text;
        }

        for (Map.Entry<String, String> replacementEntry : replacementMap.entrySet()) {
            text = StringUtils.replace(text, replacementEntry.getKey(), replacementEntry.getValue());
        }

        return text;
    }

    /**
     * 转义sql字符串
     *
     * @param sqlStr sql字符串
     * @return 转义后sql字符串
     */
    public static String escapeSql(String sqlStr) {
        return replaces(sqlStr, escapeSqlMap);
    }
}